package com.htfyun.factorytest;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.htfyun.factorytest.config.EinkProperty;
import com.htfyun.eink.EinkUtils;

import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class CpuTestActivity extends SingleTestBaseActivity implements View.OnClickListener {

    private TextView txtLog;

    private Context mContext;

    private MyHandler myHandler;

    private volatile boolean isStarted;

    private EditText editTimeHour;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //设置窗体始终点亮
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        setContentView(R.layout.activity_cpu_test);

        mContext = this;

        txtLog = findViewById(R.id.txtLog);

        findViewById(R.id.btnStart).setOnClickListener(this);
        findViewById(R.id.btnStop).setOnClickListener(this);
        findViewById(R.id.btnExit).setOnClickListener(this);

        editTimeHour = findViewById(R.id.editTimeHour);

        myHandler = new MyHandler(this);

        EinkProperty.setEinkFactoryTestEnabled(true);
        EinkUtils.setCpuFreq(mContext, EinkUtils.CPU_FREQ_LEVEL_MAX, true);

    }

    @Override
    protected void onResume() {
        super.onResume();
        FTFloatWindowService.setFloatLayoutShow(false);
    }

    @Override
    protected void onPause() {
        super.onPause();
        FTFloatWindowService.setFloatLayoutShow(true);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopCpuTest();

        EinkProperty.setEinkFactoryTestEnabled(false);
        EinkUtils.resetCpuFreqParam(mContext);

    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.btnStart:
                if (isStarted) {
                    updateLog("CPU测试 已经开始");
                    break;
                }
                isStarted = true;

                txtLog.setText("");
                updateLog("开始CPU测试");
                startCpuTest();
                break;
            case R.id.btnStop:
                updateLog("停止CPU测试");
                stopCpuTest();
                isStarted = false;
                break;
            case R.id.btnExit:
                stopCpuTest();
                setResult(RESULT_CANCELED);
                finish();
                break;
        }

    }


    private final ThreadLocal<SimpleDateFormat> SDF_THREAD_LOCAL = new ThreadLocal<>();

    @NonNull
    private SimpleDateFormat getDefaultFormat() {
        SimpleDateFormat simpleDateFormat = SDF_THREAD_LOCAL.get();
        if (simpleDateFormat == null) {
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault());
            SDF_THREAD_LOCAL.set(simpleDateFormat);
        }
        return simpleDateFormat;
    }

    private String now2String() {
        return getDefaultFormat().format(new Date());
    }

    /////////////////////

    private void startCpuTest() {

        String editString = editTimeHour.getText().toString();
        if (TextUtils.isEmpty(editString) || !TextUtils.isDigitsOnly(editString)) {
            editString = "3";
            editTimeHour.setText(editString);
        }

        int hour = Integer.parseInt(editString);
        long second = hour * 3600L;
        EinkProperty.setCpuTestMemTime(second);

        EinkProperty.clearCpuTestResult();
        EinkProperty.clearErrorBootCount();
        EinkProperty.setCpuTestMemsize(256);

        doStartCpuTest();
    }

    private void doStartCpuTest() {
        EinkProperty.startOrStopCpuTest(true);

        myHandler.removeMessages(MyHandler.MSG_CHECK_TEST_CPU);
        myHandler.sendEmptyMessageDelayed(MyHandler.MSG_CHECK_TEST_CPU, MyHandler.PERIOD_CHECK_TEST_CPU);

    }

    private void checkResultOfCpuTest() {

        updateLog("checkResultOfCpuTest, result = " + EinkProperty.getResultCpuTest());

        EinkProperty.CpuTestResultAttr attr = EinkProperty.getCpuTestResultAttr();
        switch (attr) {
            case ok:
                updateLog("Cpu 测试成功");
                isStarted = false;
                break;
            case fail:
                updateLog("Cpu 测试失败");
                isStarted = false;
                break;
            default:
                updateLog("Cpu 测试状态: " + EinkProperty.getResultCpuTest());
                myHandler.sendEmptyMessageDelayed(MyHandler.MSG_CHECK_TEST_CPU, MyHandler.PERIOD_CHECK_TEST_CPU);
                break;
        }
    }

    private void stopCpuTest() {
        myHandler.removeMessages(MyHandler.MSG_CHECK_TEST_CPU);
        EinkProperty.startOrStopCpuTest(false);

    }


    private void updateLog(String log) {
        String logWithTime = now2String() + ":" + log;
        myHandler.obtainMessage(MyHandler.MSG_UPDATE_LOG, logWithTime).sendToTarget();
    }

    private void doUpdateLog(String log) {
        String txt = txtLog.getText().toString();
        if (txt.length() > 1024 * 6) {
            txtLog.setText(log);
        } else {
            txtLog.setText(txt + "\n" + log);
        }
    }

    private static class MyHandler extends Handler {

        private static final int MSG_CHECK_TEST_CPU = 60;
        private static final int PERIOD_CHECK_TEST_CPU = 1000 * 60 * 1;// 1min


        public static final int MSG_UPDATE_LOG = 100;
        private final WeakReference<CpuTestActivity> activityWeakReference;

        private MyHandler(CpuTestActivity activity) {
            super(Looper.getMainLooper());

            activityWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            //弱引用会在下一次gc时回收
            CpuTestActivity activity = activityWeakReference.get();
            if (activity == null) {
                return;
            }

            switch (msg.what) {
                case MSG_CHECK_TEST_CPU:
                    activity.checkResultOfCpuTest();
                    break;
                case MSG_UPDATE_LOG:
                    activity.doUpdateLog((String) msg.obj);
                    break;
                default:
                    break;
            }

        }
    }

}
